package logic;

import java.util.ArrayList;
import java.util.logging.Logger;

import storage.Task;
import storage.TaskMemoryController;

import commands.*;

public class TaskDirector {
	private final static Logger LOGGER = Logger.getLogger(TaskDirector.class
			.getName());
	public static final String SPLIT_REGEX = ":";
	private String firstArg_;
	private String sndPart_;

	public static Task addTask(Task newTask) {
		// commit new task to storage
		try {
			Task createdTask = TaskMemoryController.createTask(newTask);
			return createdTask;
		} catch (Exception e) {
			return null;
		}
	}

	public static ArrayList<Task> fetchWelcomeListing() {
		return Search.getIncompleteTasksBeforeNextDays(7);
	}

	public boolean isInteger(String firstArg) {
		try {
			Integer.parseInt(firstArg);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	public String processCommand(String userInput) {
		String feedback = "";
		UndoRedoManager undoRedoManager = new UndoRedoManager();
		String[] splitInput = userInput.trim().split(" ", 2);
		firstArg_ = splitInput[0];

		// Commands that need NO additional input, just type command/shortcut
		if (firstArg_.equalsIgnoreCase(AvailableCommands.LIST.toString())
				|| firstArg_.equalsIgnoreCase(Shortcuts.L.toString())) {
			Search searchAll = new Search();
			feedback = "<Listy>!";
		} else if (firstArg_.equalsIgnoreCase(AvailableCommands.UNDO.toString())
				|| firstArg_.equalsIgnoreCase(Shortcuts.U.toString())) {
			undoRedoManager.setNotNewCommand();
			Undo undo = new Undo();
			feedback = undo.undoTask();
		} else if (firstArg_.equalsIgnoreCase(AvailableCommands.REDO.toString())
				|| firstArg_.equalsIgnoreCase(Shortcuts.RD.toString())) {
			undoRedoManager.setNotNewCommand();
			Redo redo = new Redo();
			feedback = redo.redoTask();
		} else if (firstArg_.equalsIgnoreCase(AvailableCommands.HELP.toString())
				|| firstArg_.equalsIgnoreCase(Shortcuts.H.toString())) {
			feedback = "<helpy>!";

		} else if (firstArg_.equalsIgnoreCase(AvailableCommands.QUIT.toString())
				|| firstArg_.equalsIgnoreCase(Shortcuts.Q.toString())) {
			Quit quit = new Quit();
			quit.quit();
		} else {

			// Commands that need additional user input
			try {
				sndPart_ = splitInput[1];
				String[] separatedToArgs;

				// like title and deadline
				// Add, input format: <add|a> <title>[ ]:[ ]<deadline>
				if (firstArg_.equalsIgnoreCase(AvailableCommands.ADD.toString())
						|| firstArg_.equalsIgnoreCase(Shortcuts.A.toString())) {
					undoRedoManager.setIsNewCommand();
					separatedToArgs = sndPart_.trim().split(SPLIT_REGEX, 2);
					String title = separatedToArgs[0].trim();
					String deadline = separatedToArgs[1].trim();

					Add add = new Add();
					feedback = add.addTask(title, deadline);

				// Edit, input format: <edit|e> <index>[ ]:[ ]<field>[ ]:[ ]<new input>
				} else if (firstArg_
						.equalsIgnoreCase(AvailableCommands.EDIT.toString())
						|| firstArg_.equalsIgnoreCase(Shortcuts.E.toString())) {
					undoRedoManager.setIsNewCommand();
					Edit edit = new Edit();
					separatedToArgs = sndPart_.trim().split(SPLIT_REGEX, 3);
					int index = Integer.parseInt(separatedToArgs[0].trim());
					int id = TaskMemoryController.getIdByIndex(index);
					String field = separatedToArgs[1].trim();
					String newValue = separatedToArgs[2].trim();
					feedback = edit.editTask(id, field, newValue);

				// like several arguments, some optional
				} else
				// Search, <search|s> <one or more keywords>[[ ]:[ ]<serach filter>]
				if (firstArg_.equalsIgnoreCase(AvailableCommands.SEARCH.toString())
						|| firstArg_.equalsIgnoreCase(Shortcuts.S.toString())) {
					Search searchObj = new Search();
					separatedToArgs = sndPart_.trim().split(SPLIT_REGEX, 2);
					String keywords = separatedToArgs[0].trim();
					String date;
					if (separatedToArgs.length > 1) {
						date = separatedToArgs[1].trim();
					} else {
						date = "";
					}
					feedback = searchObj.searchByStringDate(keywords, date);

				} else {

					// like an index of a task as additional input
					if (isInteger(firstArg_)) {
						// switch the values of first and second Argument
						String tmpSndArg = firstArg_;
						firstArg_ = sndPart_;
						sndPart_ = tmpSndArg;
					}
					if (firstArg_.equalsIgnoreCase(AvailableCommands.REMOVE.toString())
							|| firstArg_.equalsIgnoreCase(Shortcuts.RM.toString())) {
						undoRedoManager.setIsNewCommand();
						Remove remove = new Remove();
						feedback = remove.removeTask(TaskMemoryController
								.getIdByIndex(Integer.parseInt(sndPart_)));
					} else if (firstArg_.equalsIgnoreCase(AvailableCommands.COMPLETE
							.toString())
							|| firstArg_.equalsIgnoreCase(Shortcuts.C.toString())) {
						undoRedoManager.setIsNewCommand();
						Complete complete = new Complete();
						feedback = complete.completeTask(TaskMemoryController
								.getIdByIndex(Integer.parseInt(sndPart_)));

					} else if (firstArg_.equalsIgnoreCase(AvailableCommands.VIEW
							.toString())
							|| firstArg_.equalsIgnoreCase(Shortcuts.V.toString())) {
						undoRedoManager.setIsNewCommand();
						View view = new View();
						feedback = view.getTask(TaskMemoryController.getIdByIndex(Integer
								.parseInt(sndPart_)));
					} else {
						feedback = userInput + " is not supported.";
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
				return "Sorry, the command you typed is not supported. Please try again or have a look at help";
			}
		}
		return feedback;
	}
}
